package main

import (
	"flag"
	"fmt"
	"log"
	"sync"
	"time"

	pb "github.com/upmio/horus-polymerizer/benchmarktest/grpc"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
)

var (
	Num  int
	Conn int
	Addr string
)

const (
	ServerAddr string = "127.0.0.1:50051"
)

const RS = 100000

func NewClient() pb.EchoServiceClient {
	var opts []grpc.DialOption
	opts = append(opts, grpc.WithInsecure())
	conn, err := grpc.Dial(ServerAddr, opts...)
	if err != nil {
		log.Fatalf("fail to dial: %v", err)
	}

	return pb.NewEchoServiceClient(conn)
}

func init() {
	flag.IntVar(&Num, "num", 5, "")
	flag.IntVar(&Conn, "conn", 5, "")
	flag.StringVar(&Addr, "addr", "127.0.0.1", "")
	flag.Parse()
}

func main() {
	clients := make([]pb.EchoServiceClient, 0, 10)
	for i := 0; i < Conn; i++ {
		clients = append(clients, NewClient())
	}
	index := 0

	s1 := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

	var wg sync.WaitGroup

	start := time.Now()

	for i := 0; i < Num; i++ {
		wg.Add(1)

		var c pb.EchoServiceClient
		if index < len(clients) {
			c = clients[index]
			index++
		} else {
			index = 0
			c = clients[index]
		}

		go func(cli pb.EchoServiceClient) {
			defer wg.Done()

			log.Println("goroutine start...")
			st := time.Now()

			for n := 0; n < RS; n++ {
				if _, err := cli.Echo(context.Background(), &pb.EchoRequest{S: s1}); err != nil {
					log.Println(err)
				}
			}

			log.Println(time.Now().Sub(st))
		}(c)
	}
	wg.Wait()

	total := RS * Num
	secs := time.Now().Sub(start) / 1000000000

	fmt.Printf("concurrency: %d\n", Num)
	fmt.Printf("total: %d\n", total)
	fmt.Printf("seconds: %d\n", secs)
	fmt.Printf("qps: %d\n", total/int(secs))
}
